package utils

import "bytes"

func RemoveDuplicateInf(strs []interface{}) []interface{} {
	result := []interface{}{}
	tempMap := map[interface{}]struct{}{} // 存放不重复主键
	for _, e := range strs {
		l := len(tempMap)
		tempMap[ToString(e)] = struct{}{}
		if len(tempMap) != l { // 加入map后，map长度变化，则元素不重复
			result = append(result, e)
		}
	}
	return result
}

func RemoveDuplicateString(strs []string) []string {
	result := []string{}
	tempMap := map[string]struct{}{} // 存放不重复主键
	for _, e := range strs {
		l := len(tempMap)
		tempMap[e] = struct{}{}
		if len(tempMap) != l { // 加入map后，map长度变化，则元素不重复
			result = append(result, e)
		}
	}
	return result
}

func RemoveDuplicateInt(strs []int) []int {
	result := []int{}
	tempMap := map[int]struct{}{} // 存放不重复主键
	for _, e := range strs {
		l := len(tempMap)
		tempMap[e] = struct{}{}
		if len(tempMap) != l { // 加入map后，map长度变化，则元素不重复
			result = append(result, e)
		}
	}
	return result
}

func RemoveDuplicateUInt16(strs []uint16) []uint16 {
	set := make(map[uint16]struct{}, len(strs))
	j := 0
	for _, v := range strs {
		_, ok := set[v]
		if ok {
			continue
		}
		set[v] = struct{}{}
		strs[j] = v
		j++
	}
	return strs
}

func RemoveInt(ints []int, i int) ([]int, bool) {
	flag := -1
	for k := range ints {
		if ints[k] == i {
			flag = k
			break
		}
	}
	if flag >= 0 {
		l := len(ints)
		if flag == 0 {
			ints = ints[1:]
		} else if flag == l-1 {
			ints = ints[0:flag]
		} else {
			ints = append(ints[:flag], ints[flag+1:]...)
		}
	}
	return ints, flag >= 0
}

func AddInt(ints []int, i int) ([]int, bool) {
	flag := -1
	for k := range ints {
		if ints[k] == i {
			flag = k
			break
		}
	}
	if flag < 0 {
		ints = append(ints, i)
	}
	return ints, flag < 0
}

func RemoveByte(bytes []byte, i byte) ([]byte, bool) {
	flag := -1
	for k := range bytes {
		if bytes[k] == i {
			flag = k
			break
		}
	}
	if flag >= 0 {
		l := len(bytes)
		if flag == 0 {
			bytes = bytes[1:]
		} else if flag == l-1 {
			bytes = bytes[0:flag]
		} else {
			bytes = append(bytes[:flag], bytes[flag+1:]...)
		}
	}
	return bytes, flag >= 0
}

func AddByte(bytes []byte, i byte) ([]byte, bool) {
	flag := -1
	for k := range bytes {
		if bytes[k] == i {
			flag = k
			break
		}
	}
	if flag < 0 {
		bytes = append(bytes, i)
	}
	return bytes, flag < 0
}

func RemoveBytes(bb [][]byte, i []byte) ([][]byte, bool) {
	flag := -1
	for k := range bb {
		if bytes.Equal(bb[k], i) {
			flag = k
			break
		}
	}
	if flag >= 0 {
		l := len(bb)
		if flag == 0 {
			bb = bb[1:]
		} else if flag == l-1 {
			bb = bb[0:flag]
		} else {
			bb = append(bb[:flag], bb[flag+1:]...)
		}
	}
	return bb, flag >= 0
}

func AddBytes(bb [][]byte, i []byte) ([][]byte, bool) {
	flag := -1
	for k := range bb {
		if bytes.Equal(bb[k], i) {
			flag = k
			break
		}
	}
	if flag < 0 {
		bb = append(bb, i)
	}
	return bb, flag < 0
}

func ConcatInt(ints []uint) int {
	if ints == nil {
		return 0
	}
	k := 0
	for _, v := range ints {
		k = k | (1 << (v - 1))
	}
	return k
}
func ConcatIntByte(ints []int) int {
	if ints == nil {
		return 0
	}
	k := 0
	for _, v := range ints {
		k = k | v
	}
	return k
}

func IncludeInt(v int, s uint) bool {
	return (v & (1 << (s - 1))) > 0
}

func IncludeIntByte(v int, s int) bool {
	return v&s > 0
}

func RemoveString(strs []string, str string) ([]string, bool) {
	flag := -1
	for k := range strs {
		if strs[k] == str {
			flag = k
			break
		}
	}
	if flag >= 0 {
		l := len(strs)
		if flag == 0 {
			strs = strs[1:]
		} else if flag == l-1 {
			strs = strs[0:flag]
		} else {
			strs = append(strs[:flag], strs[flag+1:]...)
		}
	}
	return strs, flag >= 0
}

func AddString(strs []string, str string) ([]string, bool) {
	flag := -1
	for k := range strs {
		if strs[k] == str {
			flag = k
			break
		}
	}
	if flag < 0 {
		strs = append(strs, str)
	}
	return strs, flag < 0
}

func ToMap(list []string) map[string]int {
	m := map[string]int{}
	for index, value := range list {
		m[value] = index
	}
	return m
}
